﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using diploma.core.localize;
using diploma.core;
using diploma.core.data;
using diploma.core.data.objects;
using System.Xml;



namespace diploma.editor
{
    public partial class EditorControl : UserControl, ILocalizable
    {
        private string xmlText = "";
        private string originalText = "";
        private Dictionary<DataObjectTypes, DataList<diploma.core.data.IDataObject>> collection;
        public EditorControl(AbstractLocalizator _localizator, Dictionary<DataObjectTypes, DataList<diploma.core.data.IDataObject>> _collection)
        {
            collection = _collection;
            InitializeComponent();
            localizator = _localizator;
            Localize();
        }

        AbstractLocalizator localizator;

        #region ILocalizable Members

        public void Localize()
        {
            btnSave.Text = localizator.GetLocolizeWord(btnSave.Text);
            tbpEditor.Text = localizator.GetLocolizeWord(tbpEditor.Text);
            tbpThemeTree.Text = localizator.GetLocolizeWord(tbpThemeTree.Text);
            label1.Text = localizator.GetLocolizeWord(label1.Text);
            foreach (ToolStripItem m in cmsEditorTree.Items)
            {
                if (m is ToolStripMenuItem)
                {
                    m.Text = localizator.GetLocolizeWord(m.Text);
                }
            }

            foreach (ToolStripItem m in cmsEditorText.Items)
            {
                if (m is ToolStripMenuItem)
                {
                    ToolStripMenuItem mi = m as ToolStripMenuItem;
                    mi.Text = localizator.GetLocolizeWord(mi.Text);
                    if (mi.DropDownItems.Count > 0)
                    {
                        localizaMenu(mi);
                    }
                }
            }
        }

        #endregion

        private void localizaMenu(ToolStripMenuItem item)
        {
            foreach (ToolStripItem m in item.DropDownItems)
            {
                if (m is ToolStripMenuItem)
                {
                    ToolStripMenuItem mi = m as ToolStripMenuItem;
                    mi.Text = localizator.GetLocolizeWord(mi.Text);
                    if (mi.DropDownItems.Count > 0)
                    {
                        localizaMenu(mi);
                    }
                }
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(richTextBox1.Text);
            string g = doc.InnerText;
            XmlNode block = doc.GetElementsByTagName("block").Item(0);
            string topic = block.Attributes["topic"].Value;
            collection[DataObjectTypes.Theme].Add(new Theme(-1, topic, 0));
            long theme_id = collection[DataObjectTypes.Theme][collection[DataObjectTypes.Theme].Count - 1].Id;

            XmlNodeList textsList = block.ChildNodes;
            foreach (XmlElement text in textsList)
            {
                string textType = text.Attributes["type"].Value;
                switch (textType)
                {
                    case "statement":
                        XmlNodeList facts = text.GetElementsByTagName("fact");
                        foreach (XmlElement fact in facts)
                        {
                            string factType = fact.Attributes["type"].Value;
                            switch (factType)
                            {
                                case "comment":
                                    string commentTitle = "";
                                    if (fact.GetElementsByTagName("title").Count > 0)
                                    {
                                        commentTitle = fact.GetElementsByTagName("title").Item(0).InnerText;
                                    }
                                    string comment = "";
                                    if (fact.GetElementsByTagName("content").Count > 0)
                                    {
                                        comment = fact.GetElementsByTagName("content").Item(0).InnerText;
                                    }
                                    collection[DataObjectTypes.Statement].Add(new Statement(-1, commentTitle, comment, 3, theme_id));
                                    break;
                                case "suggestion":
                                    string suggestionTitle = "";
                                    if (fact.GetElementsByTagName("title").Count > 0)
                                    {
                                        suggestionTitle = fact.GetElementsByTagName("title").Item(0).InnerText;
                                    }
                                    string suggestion = "";
                                    if (fact.GetElementsByTagName("content").Count > 0)
                                    {
                                        comment = fact.GetElementsByTagName("content").Item(0).InnerText;
                                    }
                                    collection[DataObjectTypes.Statement].Add(new Statement(-1, suggestionTitle, suggestion, 4, theme_id));
                                    break;
                                case "axiom":
                                    string axiomTitle = "";
                                    if (fact.GetElementsByTagName("title").Count > 0)
                                    {
                                        axiomTitle = fact.GetElementsByTagName("title").Item(0).InnerText;
                                    }
                                    string axiomFormulation = "";
                                    if (fact.GetElementsByTagName("formulation").Count > 0)
                                    {
                                        axiomFormulation = fact.GetElementsByTagName("formulation").Item(0).InnerText;
                                    }
                                    collection[DataObjectTypes.Statement].Add(new Statement(-1, axiomTitle, axiomFormulation, 7, theme_id));
                                    break;
                                case "definition":
                                    string defTerm = "";
                                    if (fact.GetElementsByTagName("term").Count > 0)
                                    {
                                        defTerm = fact.GetElementsByTagName("term").Item(0).InnerText;
                                    }
                                    string defMeaning = "";
                                    if (fact.GetElementsByTagName("meaning").Count > 0)
                                    {
                                        defMeaning = fact.GetElementsByTagName("meaning").Item(0).InnerText;
                                    }
                                    collection[DataObjectTypes.Statement].Add(new Statement(-1, defTerm, defMeaning, 6, theme_id));
                                    break;
                                case "method":
                                    string methodTitle = "";
                                    if (fact.GetElementsByTagName("title").Count > 0)
                                    {
                                        methodTitle = fact.GetElementsByTagName("title").Item(0).InnerText;
                                    }
                                    string methodDescription = "";
                                    if (fact.GetElementsByTagName("description").Count > 0)
                                    {
                                        methodDescription = fact.GetElementsByTagName("description").Item(0).InnerText;
                                    }
                                    collection[DataObjectTypes.Statement].Add(new Statement(-1, methodTitle, methodDescription, 8, theme_id));
                                    break;
                                default:
                                    break;
                            }
                        }
                        XmlNodeList theorems = text.GetElementsByTagName("theorem");
                        foreach (XmlElement theorem in theorems)
                        {
                            string theoremType = theorem.Attributes["type"].Value;
                            switch (theoremType)
                            {
                                case "theorem":
                                    string theoremTitle = "";
                                    if (theorem.GetElementsByTagName("title").Count > 0)
                                    {
                                        theoremTitle = theorem.GetElementsByTagName("title").Item(0).InnerText;
                                    }
                                    string theoremFormulation = "";
                                    if (theorem.GetElementsByTagName("formulation").Count > 0)
                                    {
                                        theoremFormulation = theorem.GetElementsByTagName("formulation").Item(0).InnerText;
                                    }
                                    string theoremProof = "";
                                    if (theorem.GetElementsByTagName("proof").Count > 0)
                                    {
                                        theoremProof = theorem.GetElementsByTagName("proof").Item(0).InnerText;
                                    }
                                    collection[DataObjectTypes.Theorem].Add(new Theorem(-1, theoremTitle, theoremFormulation, theoremProof, 1, theme_id));
                                    break;
                                case "lemma":
                                    string lemmaTitle = "";
                                    if (theorem.GetElementsByTagName("title").Count > 0)
                                    {
                                        lemmaTitle = theorem.GetElementsByTagName("title").Item(0).InnerText;
                                    }
                                    string lemmaFormulation = "";
                                    if (theorem.GetElementsByTagName("formulation").Count > 0)
                                    {
                                        lemmaFormulation = theorem.GetElementsByTagName("formulation").Item(0).InnerText;
                                    }
                                    string lemmaProof = "";
                                    if (theorem.GetElementsByTagName("proof").Count > 0)
                                    {
                                        lemmaProof = theorem.GetElementsByTagName("proof").Item(0).InnerText;
                                    }
                                    collection[DataObjectTypes.Theorem].Add(new Theorem(-1, lemmaTitle, lemmaFormulation, lemmaProof, 2, theme_id));
                                    break;
                            }
                        }
                        break;
                    case "question":
                        string questionTitle = "";
                        if (text.GetElementsByTagName("title").Count > 0)
                        {
                            questionTitle = text.GetElementsByTagName("title").Item(0).InnerText;
                        }
                        string questionTask = "";
                        if (text.GetElementsByTagName("task").Count > 0)
                        {
                            questionTask = text.GetElementsByTagName("task").Item(0).InnerText;
                        }
                        string questionSolution = "";
                        if (text.GetElementsByTagName("solution").Count > 0)
                        {
                            questionSolution = text.GetElementsByTagName("solution").Item(0).InnerText;
                        }
                        string questionAnswer = "";
                        if (text.GetElementsByTagName("task").Count > 0)
                        {
                            questionAnswer = text.GetElementsByTagName("answer").Item(0).InnerText;
                        }
                        collection[DataObjectTypes.Problem].Add(new Problem(-1, questionTitle, questionTask, questionSolution, questionAnswer, theme_id));
                        break;
                    default:
                        break;
                }
            }
        }

        private void EditorControl_Load(object sender, EventArgs e)
        {
            tvThemes.Nodes.Clear();
            fillThemesTree(0, null);
        }

        private void fillThemesTree(long parent, TreeNode parentNode)
        {
            DataList<diploma.core.data.IDataObject> themes = collection[DataObjectTypes.Theme];
            List<Theme> _themes = new List<Theme>();
            foreach (Theme theme in themes)
            {
                if (theme.ParentId == parent)
                {
                    _themes.Add(theme);
                }
            }

            if (_themes.Count > 0)
            {
                foreach (Theme theme in _themes)
                {
                    TreeNode tr = null;
                    if (parentNode == null)
                    {
                        tr = tvThemes.Nodes.Add("" + theme.Id, theme.ToString());
                    }
                    else
                    {
                        tr = parentNode.Nodes.Add("" + theme.Id, theme.ToString());
                    }
                    fillThemesTree(theme.Id, tr);
                }
            }
            tvThemes.ExpandAll();
        }

        private void editortreemenuaddToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode selected = tvThemes.SelectedNode;
            long parent = 0;
            if (selected != null)
            {
                parent = Convert.ToInt64(selected.Name);
            }
            AddThemeForm frm = new AddThemeForm(parent, localizator);
            if (frm.ShowDialog() == DialogResult.OK)
            {
                collection[DataObjectTypes.Theme].Add(frm.NewTheme);
                EditorControl_Load(null, null);
            }
        }

        private void editortreemenudeleteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tvThemes.SelectedNode != null)
            {
                DataList<diploma.core.data.IDataObject> themes = collection[DataObjectTypes.Theme];
                long id = Convert.ToInt64(tvThemes.SelectedNode.Name);
                long parent = (themes.GetObjectById(id) as Theme).ParentId;
                foreach (Theme theme in themes)
                {
                    if (theme.ParentId == id)
                    {
                        theme.SetParentId(parent);
                    }
                }
                themes.Delete(id);
                EditorControl_Load(null, null);
            }
        }
        TreeNode tr = null;
        private void editortreemanurenameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if ((tr = tvThemes.SelectedNode) != null)
            {
                tr.BeginEdit();
            }
        }

        string oldlabel = "";
        private void tvThemes_BeforeLabelEdit(object sender, NodeLabelEditEventArgs e)
        {

            oldlabel = tvThemes.SelectedNode.Text;

        }

        private void tvThemes_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            if (!string.IsNullOrEmpty(e.Label))
            {
                (collection[DataObjectTypes.Theme].GetObjectById(Convert.ToInt64(tr.Name)) as Theme).SetTitle(e.Label);
            }

        }

        private void editortreemenumakefreeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show(localizator.GetLocolizeWord("are_you_sure"), localizator.GetLocolizeWord("confirm"), MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
            {
                if (tvThemes.SelectedNode != null)
                {
                    (collection[DataObjectTypes.Theme].GetObjectById(Convert.ToInt64(tvThemes.SelectedNode.Name)) as Theme).SetParentId(0);
                    EditorControl_Load(null, null);
                }
            }
        }

        private void editortreemenuchooseparentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            TreeNode selected = tvThemes.SelectedNode;
            if (selected != null)
            {
                long id = Convert.ToInt64(selected.Name);
                string text = selected.Text;
                List<Theme> possibleParents = new List<Theme>();
                DataList<diploma.core.data.IDataObject> themes = collection[DataObjectTypes.Theme];
                List<long> npos = new List<long>();
                isPossible(text, tvThemes.Nodes, ref npos);
                if (selected.Parent != null)
                {
                    npos.Add(Convert.ToInt64(selected.Parent.Name));
                }
                if (npos.Count != themes.Count)
                {
                    foreach (Theme theme in themes)
                    {
                        if (!npos.Contains(theme.Id))
                        {
                            possibleParents.Add(theme);
                        }
                    }
                    ChooseParentForm frm = new ChooseParentForm(id, possibleParents, localizator);
                    if (frm.ShowDialog() == DialogResult.OK)
                    {
                        (collection[DataObjectTypes.Theme].GetObjectById(id) as Theme).SetParentId(frm.Parent);
                    }
                    EditorControl_Load(null, null);
                }
            }
        }

        private bool isPossible(string text, TreeNodeCollection tr, ref List<long> npos)
        {
            bool res = true;
            foreach (TreeNode t in tr)
            {
                if (t.FullPath.IndexOf(text) >= 0)
                {
                    npos.Add(Convert.ToInt64(t.Name));
                }
                res = isPossible(text, t.Nodes, ref npos);

            }
            return res;
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            if (tbTheme.Text == "")
            {
                MessageBox.Show(localizator.GetLocolizeWord("enter_theme"), localizator.GetLocolizeWord("add_theme"), MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                string tmp = richTextBox1.Text;
                richTextBox1.Text = "<block topic=\"" + tbTheme.Text + "\">" + tmp + "</block>";
                button1_Click(null, null);
                changed = true;
            }
        }

        bool changed = false;
        private void tbcEditor_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tbcEditor.SelectedIndex == 1 && changed) { EditorControl_Load(null, null); changed = false; }
        }

        private void statementToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            string tmp = "<text type=\"statement\">" + richTextBox1.SelectedText + "</text>";
            richTextBox1.SelectedText = tmp;
        }

        private void questionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<text type=\"question\">" + richTextBox1.SelectedText + "</text>";
            richTextBox1.SelectedText = tmp;
        }

        private void commentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<fact type=\"comment\">" + richTextBox1.SelectedText + "</fact>";
            richTextBox1.SelectedText = tmp;
        }

        private void suggestionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<fact type=\"suggestion\">" + richTextBox1.SelectedText + "</fact>";
            richTextBox1.SelectedText = tmp;
        }

        private void axiomToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<fact type=\"axiom\">" + richTextBox1.SelectedText + "</fact>";
            richTextBox1.SelectedText = tmp;
        }

        private void definitionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<fact type=\"definition\">" + richTextBox1.SelectedText + "</fact>";
            richTextBox1.SelectedText = tmp;
        }

        private void titleToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            string tmp = "<title>" + richTextBox1.SelectedText + "</title>";
            richTextBox1.SelectedText = tmp;
        }

        private void contentToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<content>" + richTextBox1.SelectedText + "</content>";
            richTextBox1.SelectedText = tmp;
        }

        private void formulationToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<formulation>" + richTextBox1.SelectedText + "</formulation>";
            richTextBox1.SelectedText = tmp;
        }

        private void termToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<term>" + richTextBox1.SelectedText + "</term>";
            richTextBox1.SelectedText = tmp;
        }

        private void meaningToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<meaning>" + richTextBox1.SelectedText + "</meaning>";
            richTextBox1.SelectedText = tmp;
        }

        private void proofToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<proof>" + richTextBox1.SelectedText + "</proof>";
            richTextBox1.SelectedText = tmp;
        }

        private void taskToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<task>" + richTextBox1.SelectedText + "</task>";
            richTextBox1.SelectedText = tmp;
        }

        private void solvingToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<solving>" + richTextBox1.SelectedText + "</solving>";
            richTextBox1.SelectedText = tmp;
        }

        private void answerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<answer>" + richTextBox1.SelectedText + "</answer>";
            richTextBox1.SelectedText = tmp;
        }

        private void theoremToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            string tmp = "<theorem type=\"theorem\">" + richTextBox1.SelectedText + "</theorem>";
            richTextBox1.SelectedText = tmp;
        }

        private void lemmaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<theorem type=\"lemma\">" + richTextBox1.SelectedText + "</theorem>";
            richTextBox1.SelectedText = tmp;
        }

        private void tbpEditor_Click(object sender, EventArgs e)
        {

        }

        private void methodToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<fact type=\"method\">" + richTextBox1.SelectedText + "</fact>";
            richTextBox1.SelectedText = tmp;
        }

        private void descriptionToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string tmp = "<description>" + richTextBox1.SelectedText + "</description>";
            richTextBox1.SelectedText = tmp;
        }
    }
}
